'''
-*-  coding:  utf-8  -*-
Time    : 20:02
Auther  :罗老师
File    :relays.py
'''
import time

import serial
import serial.tools.list_ports


class RelayController:

    def __init__(self, port="COM5", baudrate=115200):
        self.ser = serial.Serial(
            port=port,
            baudrate=baudrate,
            bytesize=serial.EIGHTBITS,
            parity=serial.PARITY_NONE,
            stopbits=serial.STOPBITS_ONE,
            timeout=1)
        if not self.ser.is_open:
            raise ConnectionError("串口连接失败")
        else:
            print(f"{port}串口以成功连接")

    def set_dealy(self, lst):
        """
        :param lst: 传入4路电路的开关状态  1：开，0：关
        :return:
        """
        #  继电器跳线设置 # 控制4路开关的开合和关闭状态
        ser_dict = {
            "CH1": [0xFF, 0x01, 0x00, 0xFF],
            "CH2": [0xFF, 0x02, 0x00, 0xFF],
            "CH3": [0xFF, 0x03, 0x00, 0xFF],
            "CH4": [0xFF, 0x04, 0x00, 0xFF]
        }
        state = 0
        for i in ser_dict.keys():
            ser_dict[i][2] = lst[state]
            if lst[state]:
                ser_dict[i][3] = 0xFE
            common_cmd = bytes(ser_dict[i])
            self.ser.write(common_cmd)
            time.sleep(0.2)
            state += 1

    # 读取继电器当前状态
    def read_channel_state(self):
        response = self.ser.read_all()
        if len(response) < 3:
            # 这个需要确认返回的规范
            raise ValueError("无效响应数据")
        # 返回的消息如何定义需要有对应的协议来确认
        data = response[3]
        if data == "0XF":
            return [1, 0, 1, 1]

    def close(self):
        self.ser.close()


# 发现继电器串口设备，
def Relay_port_list():
    ports = serial.tools.list_ports.comports()
    if not ports:
        print("未检测到串口信息")
        return
    for port in ports:
        if "CH340" in port.description:
            print(f"端口：{port.device}")
            print(f"串口描述：{port.description}")
            print(f"硬件ID：{port.hwid}")
            return port.device


# 编写一个主流程控制方法，确认继电器的控制流程
if __name__ == "__main__":
    relay = RelayController(port=Relay_port_list())
    try:
        lst = [1, 0, 1, 1]
        relay.set_dealy(lst)
    except Exception as e:
        print(f"命令执行失败：{e}")
    finally:
        relay.close()
